/**
 * All Rights Reserved , Copyright (C) 2021 , 青岛鼎信通讯股份有限公司
 * BaseFlowRoleService
 * 流程角色
 * 修改纪录
 * 2021-01-11 版本：1.0 wanghanwei 创建。
 *
 * @version 版本：1.0
 * @author 作者：wanghanwei
 * 创建日期：2021-01-11
 */
package com.topscomm.base.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.topscomm.base.BaseSystemConst.BaseFlowRoleUserTypeEnum;
import com.topscomm.base.pojo.BaseFlowRoleLinkInsEntity;
import com.topscomm.base.service.IBaseFlowRoleLinkInsService;
import com.topscomm.base.service.IBaseFlowRoleService;
import com.topscomm.base.service.impl.auto.BaseFlowRoleServiceAuto;
import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.exception.ServiceException;
import com.topscomm.basic.util.PrimaryKeyUtil;
import com.topscomm.cbo.pojo.CboApprovalFlowInsEntity;
import com.topscomm.cbo.service.ICboApprovalFlowInsService;
import com.topscomm.pub.util.BaseUtil;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.pub.util.StringUtil;
import com.topscomm.pub.vo.ResponseResult;

@Service(value = "baseFlowRoleService")
@Scope(value = "singleton")
public class BaseFlowRoleService extends BaseFlowRoleServiceAuto implements IBaseFlowRoleService {
	@Autowired
	IBaseFlowRoleLinkInsService baseFlowRoleLinkInsService;
	@Autowired
	ICboApprovalFlowInsService cboApprovalFlowInsService;

	/**
	 * @description:新增前处理
	 * @auther: wanghanwei
	 * @date: 2021年1月13日下午6:34:36
	 * @modify:
	 */
	@Override
	protected void beforeInsert(BasicEntity entity) throws ServiceException {
		super.beforeInsert(entity);
		if (entity.getId() <= 0) {// 赋值Id和单号
			long[] arrayId = PrimaryKeyUtil.GeneIDs(entity.getTableName(), 1);
			entity.setId(arrayId[0]);
		}
	}

	protected List<Map<String, Object>> removeRepeatMapByKey(List<Map<String, Object>> list, String mapKey) {
		// 把list中的数据转换成msp,去掉同一id值多余数据，保留查找到第一个id值对应的数据
		List<Map<String, Object>> listMap = new ArrayList<>();
		Map<String, Map> msp = new HashMap<>();
		for (int i = list.size() - 1; i >= 0; i--) {
			Map map = list.get(i);
			String id = ConvertUtil.convertToString(map.get(mapKey));
			map.remove(mapKey);
			msp.put(id, map);
		}
		// 把msp再转换成list,就会得到根据某一字段去掉重复的数据的List<Map>
		Set<String> mspKey = msp.keySet();
		for (String key : mspKey) {
			Map newMap = msp.get(key);
			newMap.put(mapKey, key);
			listMap.add(newMap);
		}
		return listMap;
	}

	/**
	 * @description:申请单审批后，生成组建团队的节点审批人
	 * @param sourceType
	 * @param sourceId
	 * @param flowId
	 * @return
	 * @author: zhanglongfei
	 * @date: 2021年3月6日上午9:37:32
	 * @modify:
	 */
	@Override
	public void generateApprovalRole(String sourceType, String sourceId, long flowId) {
		Map<String, Object> paraMap = new HashMap<>();
		paraMap.put("sourcetype", sourceType);
		paraMap.put("sourceid", sourceId);
		paraMap.put("flowid", flowId);
		// 获取单据所在省区编码
		String deptCommonCode = "";
		List<Map<String, Object>> scopeDeptList = this.queryMap(paraMap, "selectScopeDeptByFlowId");
		if (scopeDeptList.get(0) != null && !scopeDeptList.isEmpty() && scopeDeptList != null) {
			deptCommonCode = ConvertUtil.convertToString(scopeDeptList.get(0).get("deptcommoncode"));
		}
		// 查询角色表的拓展产品线相关字段，获取到所有特殊（非通用）角色配置code,relationkey,relationtable,souceidcolumn
		List<Map<String, Object>> flowRoleList = this.queryMap(paraMap, "selectBaseFlowRoleByFlowId");
		if (flowRoleList.size() > 0) {
			StringBufferProxy sqlBufferProxy = new StringBufferProxy();
			for (Map<String, Object> flowRole : flowRoleList) {
				sqlBufferProxy.appendLineSingle(" or (flowRole.roletype='1' and flowRole.code in (select {0} from {1} where {2}='{3}') and relationtable='{1}' and relationkey='{0}')", flowRole
						.get("relationkey"), flowRole
								.get("relationtable"), flowRole.get("souceidcolumn"), sourceId);
			}
			paraMap.put("specialRoleWhere", sqlBufferProxy.toString());
		}
		List<Map<String, Object>> roleUserList = this.queryMap(paraMap, "selectRoleForFlow");
		Map<String, List<Map<String, Object>>> listMap = roleUserList.stream()
				.collect(Collectors.groupingBy(map -> map.get("roleid").toString()));
		// 是否有省区
		boolean hasDeptCommon = !StringUtil.isEmpty(deptCommonCode);
		List<Map<String, Object>> allList = new ArrayList<>();
		// 循环所有人员，查找每个角色下的联系人
		for (Map.Entry<String, List<Map<String, Object>>> entry : listMap.entrySet()) {
			List<Map<String, Object>> linkManList = entry.getValue().stream().filter(map -> BaseFlowRoleUserTypeEnum.LinkMan.equals(ConvertUtil.convertToString(map.get("usertype"))))
					.collect(Collectors.toList());
			if (linkManList.size() == 0) {
				throw new ServiceException("角色【" + entry.getValue().get(0).get("name") + "】下没有对接人，请联系管理员添加！");
			}
			if (hasDeptCommon) {
				// 有省份时，优先选择对应省份的
				final String commonCode = deptCommonCode;
				Optional<Map<String, Object>> matchedResult = linkManList.stream()
						.filter(map -> "1".equals(ConvertUtil.convertToString(map.get("scopetype")))
								&& Arrays.asList(ConvertUtil.convertToString(map.get("scopedept")).split(",")).contains(commonCode))
						.findFirst();
				if (matchedResult.isPresent()) {
					allList.add(matchedResult.get());
					continue;
				}
			}
			// 在没有区分省区时，获取所有省区
			Optional<Map<String, Object>> matchedResult = linkManList.stream().filter(map -> "0".equals(ConvertUtil.convertToString(map.get("scopetype")))).findFirst();
			if (!matchedResult.isPresent()) {
				throw new ServiceException("角色【" + entry.getValue().get(0).get("name") + "】下没有对接人，请联系管理员添加！");
			}
			allList.add(matchedResult.get());
		}
		// 插入到新表
		baseFlowRoleLinkInsService.deleteByWhere("sourcetype='" + sourceType + "' and sourceid='" + sourceId + "' and flowid=" + flowId + " ");
		List<BasicEntity> insertList = new ArrayList<>();
		Date now = new Date();
		for (Map<String, Object> inserMap : allList) {
			BaseFlowRoleLinkInsEntity linkInsEntity = new BaseFlowRoleLinkInsEntity();
			linkInsEntity.setCreateon(now);
			linkInsEntity.setFlowid(flowId);
			linkInsEntity.setSourceid(sourceId);
			linkInsEntity.setSourcetype(sourceType);
			linkInsEntity.setDeptcommoncode(deptCommonCode);
			linkInsEntity.setRelationtype(ConvertUtil.convertToString(inserMap.get("relationtype")));
			linkInsEntity.setRolecode(ConvertUtil.convertToString(inserMap.get("code")));
			linkInsEntity.setRoleid(ConvertUtil.convertToLong(inserMap.get("roleid")));
			linkInsEntity.setRolename(ConvertUtil.convertToString(inserMap.get("name")));
			linkInsEntity.setUsercode(ConvertUtil.convertToString(inserMap.get("usercode")));
			linkInsEntity.setUserid(ConvertUtil.convertToLong(inserMap.get("userid")));
			linkInsEntity.setUsername(ConvertUtil.convertToString(inserMap.get("username")));
			linkInsEntity.setUsertype(ConvertUtil.convertToString(inserMap.get("usertype")));
			insertList.add(linkInsEntity);
		}
		baseFlowRoleLinkInsService.insertBatch(insertList);
	}

	/**
	 * @description:审批组建团队组件，获取成员
	 * @param paraMap
	 * @return
	 * @author: zhanglongfei
	 * @date: 2021年3月8日下午2:42:55
	 * @modify:
	 */
	@Override
	public List<Map<String, Object>> queryRoleUserList(Map<String, Object> paraMap) {
		if ("true".equals(paraMap.get("view"))) {
			// 查看模式下，看所有的实例数据
			return queryRoleUserInsList(paraMap);
		} else {
			// 编辑模式下，看自己的数据
			return queryLiveRoleUserList(paraMap);
		}
	}

	/**
	 * @description:获取实时的最新角色池数据
	 * @param paraMap
	 * @return
	 * @author: zhanglongfei
	 * @date: 2021年3月8日下午3:57:28
	 * @modify:
	 */
	private List<Map<String, Object>> queryLiveRoleUserList(Map<String, Object> paraMap) {
		// 查询所有，不区分对接人，在项目经理组件团队的节点，1是预组建团队，2是团队确认，两个的区别就是团队确认，要判断人员必须选，而预组建可以只选择其中的几个
		boolean queryAll = "1".equals(ConvertUtil.convertToString(paraMap.get("queryAll"))) || "2".equals(ConvertUtil.convertToString(paraMap.get("queryAll")));
		if (!queryAll)
			paraMap.put("linkuserid", getSessionUserBean().getUser().getId());
		// 获取单据所在省区编码
		List<Map<String, Object>> scopeDeptList = this.queryMap(paraMap, "selectScopeDeptByFlowId");
		if (scopeDeptList.get(0) != null && !scopeDeptList.isEmpty() && scopeDeptList != null) {
			paraMap.put("deptcommoncode", ConvertUtil.convertToString(scopeDeptList.get(0).get("deptcommoncode")));
		} else {
			// 因为sql语句中需要这个参数，所以增加默认值，便于查询不到省区数据
			paraMap.put("deptcommoncode", "'无省区信息'");
		}
		// 获取之前设置过的人员
		List<Map<String, Object>> userInsList = this.queryMap(paraMap, "selectUserCodeInsByFlowInsId");
		Map<String, List<Map<String, Object>>> userCodeMap = userInsList.stream()
				.collect(Collectors.groupingBy(map -> map.get("roleid").toString()));
		// 获取资源池中的人员
		List<Map<String, Object>> userList = queryMap(paraMap, "selectRoleUserForFlow");
		Map<String, List<Map<String, Object>>> groupList = userList.stream().collect(Collectors.groupingBy(map -> map.get("roleid").toString(), LinkedHashMap::new, Collectors.toList()));
		List<Map<String, Object>> resultList = new ArrayList<>();
		for (Map.Entry<String, List<Map<String, Object>>> entry : groupList.entrySet()) {
			Map<String, Object> itemMap = new HashMap<String, Object>();
			List<String> rolelnslist = new ArrayList<String>();
			List<Map<String, Object>> userCodeList = userCodeMap.get(entry.getKey());
			// 如果之前没选择过，则默认选中自己
			if (userCodeList == null || userCodeList.size() == 0) {
				// rolelnslist.add(ConvertUtil.convertToString(entry.getValue().get(0).get("usercode")));+
				if (!queryAll) {
					rolelnslist.add(getSessionUserBean().getUser().getCode());
				}
			} else if (userCodeList != null && !userCodeList.isEmpty()) {
				// 如果之前选过，则选中之前选过的人
				for (Map<String, Object> userCode : userCodeList) {
					rolelnslist.add(ConvertUtil.convertToString(userCode.get("usercode")));
				}
			}
			itemMap.put("name", entry.getValue().get(0).get("name"));
			itemMap.put("sortcode", entry.getValue().get(0).get("rolesortcode"));
			List<Map<String, Object>> roleUserList = entry.getValue();
			// 由于有可能存在没有用户的情况，这时候会出现左连接的用户信息都是null
			if (roleUserList.size() == 1 && roleUserList.get(0).get("id") == null) {
				roleUserList = new ArrayList<>();
			}
			itemMap.put("roleuserlist", roleUserList);
			itemMap.put("rolelnslist", rolelnslist);
			resultList.add(itemMap);
		}
		return resultList;
	}

	/**
	 * @description:获取已选择的人员
	 * @param paraMap
	 * @return
	 * @author: zhanglongfei
	 * @date: 2021年3月8日下午4:26:51
	 * @modify:
	 */
	private List<Map<String, Object>> queryRoleUserInsList(Map<String, Object> paraMap) {
		List<Map<String, Object>> userList = this.queryMap(paraMap, "selectUserInsByFlowInsId");
		CboApprovalFlowInsEntity flowInsEntity = cboApprovalFlowInsService.queryById(ConvertUtil.convertToString(paraMap.get("flowinsid")));
		List<BaseFlowRoleLinkInsEntity> linkList = baseFlowRoleLinkInsService.queryByWhere("sourcetype='" + flowInsEntity.getSourcetype() + "' and sourceid='" + flowInsEntity.getSourceid()
				+ "' and flowid='" + flowInsEntity.getFlowid() + "'");
		Map<String, List<Map<String, Object>>> listMap = userList.stream()
				.collect(Collectors.groupingBy(map -> map.get("roleid").toString()));
		Map<String, Object> itemMap;
		List<Map<String, Object>> resultList = new ArrayList<>();
		for (Map.Entry<String, List<Map<String, Object>>> entry : listMap.entrySet()) {
			itemMap = new HashMap<String, Object>();
			if (CollectionUtils.isEmpty(entry.getValue())) {
				break;
			}
			Map<String, Object> roleInsMap = entry.getValue().get(0);
			Optional<BaseFlowRoleLinkInsEntity> linkEntityOptional = linkList.stream().filter(m -> m.getRoleid() == ConvertUtil.convertToLong(roleInsMap.get("roleid"))).findFirst();
			if (linkEntityOptional.isPresent()) {
				itemMap.put("handleusercode", linkEntityOptional.get().getUsercode());
			} else {
				itemMap.put("handleusercode", roleInsMap.get("handleusercode"));
			}
			itemMap.put("name", roleInsMap.get("rolename"));
			List<String> userCodeList = entry.getValue().stream().map(map -> map.get("usercode").toString())
					.collect(Collectors.toList());
			itemMap.put("rolelnslist", userCodeList);
			itemMap.put("roleuserlist", entry.getValue());
			resultList.add(itemMap);
		}
		return resultList;
	}

	/**
	 * @description:组件查询接口
	 * @auther: wanghanwei
	 * @date: 2021年1月15日下午8:09:46
	 * @modify:
	 */
	@Override
	public ResponseResult<Object> queryElementList(Map<String, Object> paraMap) {
		paraMap = BaseUtil.decodeSecureMap(paraMap);
		List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>();
		if ("true".equals(paraMap.get("view"))) {
			// 组建团队节点 查看
			List<Map<String, Object>> userList = this.queryMap(paraMap, "selectUserInsByFlowInsId");
			Map<String, List<Map<String, Object>>> listMap = userList.stream()
					.collect(Collectors.groupingBy(map -> map.get("roleid").toString()));
			Map<String, Object> itemMap;
			for (Map.Entry<String, List<Map<String, Object>>> entry : listMap.entrySet()) {
				itemMap = new HashMap<String, Object>();
				if (CollectionUtils.isEmpty(entry.getValue())) {
					break;
				}
				itemMap.put("name", entry.getValue().get(0).get("rolename"));
				List<String> userCodeList = entry.getValue().stream().map(map -> map.get("usercode").toString())
						.collect(Collectors.toList());
				itemMap.put("rolelnslist", userCodeList);
				itemMap.put("roleuserlist", entry.getValue());
				dataList.add(itemMap);
			}
		} else {
			// 组建团队节点 新增
			// 获取之前设置过的人员
			List<Map<String, Object>> userInsList = this.queryMap(paraMap, "selectUserCodeInsByFlowInsId");
			Map<String, List<Map<String, Object>>> userCodeMap = userInsList.stream()
					.collect(Collectors.groupingBy(map -> map.get("roleid").toString()));
			// 查询人员权限范围
			// 获取当前业务单据的省区
			List<Map<String, Object>> scopeDeptList = this.queryMap(paraMap, "selectScopeDeptByFlowId");
			if (scopeDeptList.get(0) != null && !scopeDeptList.isEmpty() && scopeDeptList != null) {
				paraMap.put("deptcommoncode", scopeDeptList.get(0).get("deptcommoncode"));
			}
			// 查询角色表的拓展产品线相关字段，获取到所有特殊（非通用）角色配置
			List<Map<String, Object>> baseFlowList = this.queryMap(paraMap, "selectBaseFlowRoleByFlowId");
			Map<String, Map<String, Object>> relationtData = new HashMap<String, Map<String, Object>>();
			List<Map<String, Object>> userList = new ArrayList<Map<String, Object>>();
			userList.addAll(this.queryMap(paraMap, "selectUserByFlowId"));
			if (baseFlowList.size() > 0) {
				for (Map<String, Object> baseFlow : baseFlowList) {
					if (!relationtData.containsKey(baseFlow.get("relationtable"))) {
						paraMap.put("useunion", "1");
						Map<String, Object> tableData = new HashMap<String, Object>();
						paraMap.put("relationtable", baseFlow.get("relationtable"));
						paraMap.put("relationkey", baseFlow.get("relationkey"));
						paraMap.put("souceidcolumn", baseFlow.get("souceidcolumn"));
						relationtData.put(baseFlow.get("relationtable").toString(), tableData);
						// 查询角色和人员总体数据
						userList.addAll(this.queryMap(paraMap, "selectUserByFlowId"));
					}
				}
			}
			if (userList.size() > 0) {
				userList = this.removeRepeatMapByKey(userList, "id");
			}
			// 按照订单编号去重
			Map<String, List<Map<String, Object>>> listMap = userList.stream()
					.collect(Collectors.groupingBy(map -> map.get("roleids").toString()));
			// if (baseFlowList != null && !baseFlowList.isEmpty()) {
			// paraMap.put("relationtable", baseFlowList.get(0).get("relationtable"));
			// paraMap.put("relationkey", baseFlowList.get(0).get("relationkey"));
			// paraMap.put("souceidcolumn", baseFlowList.get(0).get("souceidcolumn"));
			// }
			// 查询角色和人员总体数据
			// List<Map<String, Object>> userList = this.queryMap(paraMap, "selectUserByFlowId");
			// Map<String, List<Map<String, Object>>> listMap = userList.stream()
			// .collect(Collectors.groupingBy(map -> map.get("roleids").toString()));
			Map<String, Object> itemMap;
			for (Map.Entry<String, List<Map<String, Object>>> entry : listMap.entrySet()) {
				itemMap = new HashMap<String, Object>();
				if (CollectionUtils.isEmpty(entry.getValue())) {
					break;
				}
				List<String> rolelnslist = new ArrayList<String>();
				List<Map<String, Object>> userCodeList = userCodeMap.get(entry.getKey());
				if (userInsList.size() == 0 && entry.getValue().get(0).get("id") != null) {
					rolelnslist.add(ConvertUtil.convertToString(entry.getValue().get(0).get("usercode")));
				} else if (userCodeList != null && !userCodeList.isEmpty()) {
					for (Map<String, Object> userCode : userCodeList) {
						rolelnslist.add(ConvertUtil.convertToString(userCode.get("usercode")));
					}
				}
				itemMap.put("name", entry.getValue().get(0).get("name"));
				itemMap.put("roleuserlist", entry.getValue());
				itemMap.put("rolelnslist", rolelnslist);
				dataList.add(itemMap);
			}
		}
		return ResponseResult.ok(dataList);
	}
}
